#pragma once

#include <stdexcept>
#include <string>
#include <sstream>
#include <Windows.h>
#include <sstream>
#include <string>
#include <iostream>

namespace DirectXUI {

	class InvalidOperationException : public std::runtime_error
	{
	public:
		InvalidOperationException(std::string message) : std::runtime_error(message) {}
	};

	class NullArgumentException : public std::invalid_argument
	{
	public:
		NullArgumentException(std::string argName) : std::invalid_argument(argName + " can't be null.")
		{
		}
	};

	class SystemException : public std::runtime_error {
	public:
		SystemException(std::string message) : std::runtime_error(message) {}
	};

	class HandleResultException : public std::runtime_error
	{
	private:
		const HRESULT _hr;
		std::string MakeMessage(HRESULT hr)
		{
			std::stringstream ss;
			ss << "System runtime error, code is 0x" << std::hex << hr << ".";
			return ss.str();
		}
	public:
		HandleResultException(HRESULT hr) : _hr(hr), std::runtime_error(MakeMessage(hr))
		{
		}
		HRESULT Error() const { return _hr; }

		inline static void ThrowIfFailed(HRESULT hr)
		{
			if (FAILED(hr))
			{
				throw HandleResultException(hr);
			}
		}
	};
}